--
-- Created by IntelliJ IDEA.
-- User: bluda
-- Date: 2018/8/21
-- Time: 11:03
-- To change this template use File | Settings | File Templates.
-- 战场

cc.exports.FindPath = import("app.model.battlefield.FindPath")
cc.exports.AttackUnit = import("app.model.battlefield.AttackUnit")
cc.exports.Military = import("app.model.battlefield.Military")
cc.exports.FightUnit = import("app.model.battlefield.FightUnit")
cc.exports.Sowar = import("app.model.battlefield.Sowar")
cc.exports.Formation = import("app.model.battlefield.Formation")
cc.exports.Squad = import("app.model.battlefield.Squad")

local DRAW_GRID = true
local MAN_POSITION = 10000

local Battlefield = {
    military1 = nil,
    military2 = nil,
    weather = "sun",
    terrain = "glassland",
    hour = 20,
    wind = "breeze",
    countdown = 0,
    mapId = "glassland1",
    state = "stop", -- start, pause, stop
    size = nil,
    gridMap = {},
    gridRows = BATTELFIELD_GRID,
    fragSize = {width=0, height=0},
    envEffects = {    -- 0 - 1000 可以移动， > 1000 不可以移动  > 10000  上面位置被人占据
        {msd=0, asd=0, avd=0, hpd=0, dsd=0.6},
        {msd=0.5, asd=0.5, avd=0.6, hpd=10, dsd=0.6}
    },
    weatherEffects = {
        rain = {},
        eastWind = {},
    },
    currentWeather = {"rain", "eastWind"};
    
    attackUnitsCounter = 1,
    attackUnits = {},
    sceneNode = nil,
    
    sceneArea = {x=0, y=0, width=0, height=0 },
    
    camera = nil
}



function Battlefield:processAttackUnits(dt, ct, ci)
    local count = 1
    for i = 1, #self.attackUnits do
        local unit = self.attackUnits[count]
        --unit:process(dt, ct, ci)
        if unit:isDone() then
            unit.ui:removeFromParent()
            table.remove(self.attackUnits, count)
            count = count - 1
        end
        count = count + 1
    end
end


-- 开始战斗
function Battlefield:start()
    -- 设置一个定时
    self.state = "start"
    self.sceneNode:resume()
    cc.Director:getInstance():startAnimation()
end

function Battlefield:isStart()
    return self.state == "start"
end

function Battlefield:pause()
    self.state = "pause"
    self.sceneNode:pause()
    cc.Director:getInstance():stopAnimation()
end

-- 创建战场
function Battlefield:create(mapId, area, userdata1, userdata2)
    math.randomseed(os.time())

    local bf = xcopy(Battlefield)
    bf.size = {width=area.width,height=area.height}
    bf.mapId = mapId
    bf.military1 = Military:create(bf, "己方", userdata1, true)
    bf.military2 = Military:create(bf, "敌方", userdata2, false)

    bf.military1:setTargetMilitary(bf.military2)
    bf.military2:setTargetMilitary(bf.military1)

    bf:initMap()
    
    bf.fragSize.width = area.width/bf.gridRows
    bf.fragSize.height = area.height/bf.gridRows
    return bf
end

function Battlefield:initMap()
    -- 初始化网格, 0地面，1水地，2可以跳过去得敌方
    for r = 1, self.gridRows do
        self.gridMap[r] = {}
        for c = 1, self.gridRows do
            self.gridMap[r][c] = {}
            self.gridMap[r][c].v = 1
            self.gridMap[r][c].unit = Set()
--            if c > self.gridRows / 3 and c < self.gridRows * 2 / 3 and r > self.gridRows / 3 and r < self.gridRows * 2 / 3 then
--                self.gridMap[r][c].v = 1001
--            end
        end
    end
end

function Battlefield:initUI(node)
    self.sceneArea.x, self.sceneArea.y = node:getPosition()
    local sceneSize = node:getContentSize()
    self.sceneArea.width = sceneSize.width
    self.sceneArea.height = sceneSize.height
    xprint(self.sceneArea)

    if DRAW_GRID == true then

        local mapUI = cc.DrawNode:create()
        for r = 0, self.gridRows do
            mapUI:drawSegment({x=0, y=r*self.fragSize.height}, {x=self.size.width, y=r*self.fragSize.height }, 0.5
                , cc.c4b(0,55,55, 222))
        end
    
        for c = 0, self.gridRows do
            mapUI:drawSegment({x=c*self.fragSize.width, y=0}, {x=c*self.fragSize.width, y=self.size.height }, 0.5
                , cc.c4b(0,55,55, 222))
        end
    
        mapUI:addTo(node)
    
    
        local mapUI = cc.DrawNode:create()
        mapUI:addTo(node)
        self.mapUI= mapUI
    end

    local spriteFrame = cc.SpriteFrameCache:getInstance()
    spriteFrame:addSpriteFrames("fight/solders.plist")
    
    self.military1:initUI(node, true)
    self.military2:initUI(node, false)
    self.sceneNode = node

    local tt = 0
    self.sceneNode:getScheduler():scheduleScriptFunc(function(dt)
        if self.state == "start" then
--            dt = os.clock() - tt
--            if tt == 0 then
--                dt = 0.016
--                tt = os.clock()
--            end
            
            local tt = os.clock()
            self.military1:process(dt, os.clock(), 0)
            local t1 = os.clock() - tt
            self.military2:process(dt, os.clock(), 0)
            local t2 = os.clock() - tt - t1
            self:processAttackUnits(dt, os.clock(), 0)
            local t3 = os.clock() - tt - t2 - t1
            --self:refreshMapUI()
            --logW("delta time : " .. string.format("%2f", dt), string.format("%2f", os.clock()-tt)
            --    , string.format("%2f", t1), string.format("%2f", t2), string.format("%2f", t3))
        
            
        end
    end, 1/60, false)
    
    self:focusPoint(0, 0)
    self:zoomNormal()
    self:refreshMapUI()
    self:refreshWeather()
end

function Battlefield:refreshMapUI()
    if DRAW_GRID == true then
    -- 绘制地图
        local mapUI = self.mapUI
        mapUI:clear()
    
        for r = 1, #self.gridMap do
            for c = 1, #self.gridMap[r] do
                if self.gridMap[r][c].v >= 1 and self.gridMap[r][c].v <= 1000 then
                    mapUI:drawSolidRect({x=(c - 1) * self.fragSize.width, y=(r - 1) * self.fragSize.height}
                        , {x=c * self.fragSize.width, y=r * self.fragSize.height}, cc.c4b(0,0,0,0))
                elseif self.gridMap[r][c].v >= 1001 and self.gridMap[r][c].v < 10000 then
                    mapUI:drawSolidRect({x=(c - 1) * self.fragSize.width, y=(r - 1) * self.fragSize.height}
                        , {x=c * self.fragSize.width, y=r * self.fragSize.height}, cc.c4b(205,11,33,128))
                else
                    mapUI:drawSolidRect({x=(c - 1) * self.fragSize.width, y=(r - 1) * self.fragSize.height}
                        , {x=c * self.fragSize.width, y=r * self.fragSize.height}, cc.c4b(66,66,33,128))
                end
            end
        end
    
    end
end


function Battlefield:refreshWeather()
    self:refreshWeatherUI()
end

function Battlefield:refreshWeatherUI()
--    self.sceneNode:removeChildByTag(9999)
--    local rainUI = cc.ParticleRain:create()
--    rainUI:setTexture(cc.Director:getInstance():getTextureCache():addImage("streak.png"));
--    rainUI:setSpeed(1000.0);
--    self.sceneNode:addChild(rainUI, 9999, 9999);
end

function Battlefield:addAttackUnit(au)
    table.insert(self.attackUnits, au)
    au.ui:addTo(self.sceneNode)
    au.ui:setPosition(au.currentPosition)
end

function Battlefield:hasGridTake(pxPostion) 
    return self:getGridValue(pxPostion) >= MAN_POSITION
end

function Battlefield:getGridUnits()
    return self.gridMap[r][c].units
end

function Battlefield:resetSelfGrid(unit)
    local pxPostion = unit.position

    local c, r = math.floor((pxPostion.x) / self.fragSize.width) + 1
        , math.floor((pxPostion.y) / self.fragSize.height) + 1
    self.gridMap[r][c].v = self.gridMap[r][c].v + MAN_POSITION
    self.gridMap[r][c].unit:insert(unit)
    --logW(c, r, "grid unit length : " .. #self.gridMap[r][c].unit)
    return c, r
end

function Battlefield:clearSelfGrid(unit)
    local pxPostion = unit.position
    local c, r = math.floor((pxPostion.x) / self.fragSize.width) + 1
        , math.floor((pxPostion.y) / self.fragSize.height) + 1
    if self.gridMap[r][c].v > MAN_POSITION then
        self.gridMap[r][c].v = self.gridMap[r][c].v - MAN_POSITION
    end

    self.gridMap[r][c].unit:remove(unit)
    --logW(c, r, "grid unit length : " .. #self.gridMap[r][c].unit)

    return c, r 

end


function Battlefield:getGridMap()
    return self.gridMap
end


function Battlefield:getGridByPosition(position)
    local c, r = math.floor((position.x) / self.fragSize.width) + 1
    , math.floor((position.y) / self.fragSize.height) + 1
    return c, r
end

function Battlefield:getPositionByGrid(grid) 
    local x, y = (grid.c - 0.5) * self.fragSize.width, (grid.r - 0.5) * self.fragSize.height
    return x, y
end

function Battlefield:getGridValue(pxPostion)
    local c = math.floor((pxPostion.x) / self.fragSize.width) + 1
    local r = math.floor((pxPostion.y) / self.fragSize.height) + 1

    if c < 1 or r < 1 then
        return 1    
    end

    if r > self.gridRows or c > self.gridRows then
        return 1
    end

    return self.gridMap[r][c].v or 1
end

function Battlefield:getEnvEffect(pxPosition)
    local c = math.floor((pxPosition.x) / self.fragSize.width) + 1
    local r = math.floor((pxPosition.y) / self.fragSize.height) + 1
    
    if c < 1 or r < 1 then
        return self.envEffects[1]
    end

    if r > self.gridRows or c > self.gridRows then
        return self.envEffects[1]
    end


    local v = self.gridMap[r][c].v or 1
    -- logW("grid position " , r, c, v)

    if v >= MAN_POSITION then
        v = v - MAN_POSITION
    end
    return self.envEffects[v] or self.envEffects[1]
end

function Battlefield:getSceneNode()
    return self.sceneNode
end

function Battlefield:setContentSize(size)
    self.size = size
end

function Battlefield:getContentSize()
    return self.size
end

function Battlefield:isInBattlefieldArea(position) 
    if position.x < 0 or position.x > self.size.width then
        logW("isInBattlefieldArea x false", position.x)
        return false
    end

    if position.y < 0 or position.y > self.size.height then
        logW("isInBattlefieldArea y false", position.y)
        return false
    end
    
    return true
end


function Battlefield:cleanUnit(unit)
    self.sceneNode:removeChild(unit.ui, true)
end

-- 选择一个单元
function Battlefield:chooseUnit(position, notMilitary)
    local c, r = math.floor((position.x) / self.fragSize.width) + 1
        , math.floor((position.y) / self.fragSize.height) + 1
    logW(c, r, "grid unit length : " .. #self.gridMap[r][c].unit)

    -- 选择周边1级
    for i=1, #NEAR_GRID_CHOOSE do
        c = c + NEAR_GRID_CHOOSE[i][1]
        r = r + NEAR_GRID_CHOOSE[i][2]

        if c <= self.gridRows and c > 1 and r > 1 and r <= self.gridRows then
            if self.gridMap[r][c].v > MAN_POSITION then
                local unit = self.gridMap[r][c].unit[1]
                if notMilitary ~= nil then
                    if unit.military ~= notMilitary then
                        return self.gridMap[r][c].unit[1]
                    end
                else
                    return unit
                end
            end
        end
    end
    
    return nil
end


-- 缩放
function Battlefield:zoomUp(delta)
    local scale = self.sceneNode:getScale()
    logW("zoomDown", delta, scale)
    scale = scale + delta * 0.1
    if scale < 1 then
        scale = 1    
    end
    self.sceneNode:setScale(scale)
end

-- 还原到原始大小
function Battlefield:zoomNormal()
    self.sceneNode:setScale(2.0)
end

-- 设置焦点区域
function Battlefield:focusPoint(x, y)
    local positionx,positiony = self.sceneNode:getPosition()
    logW("position = " , positionx, positiony)
    self.sceneNode:setPosition(positionx - x, positiony - y)
end

function Battlefield:makeSquad(military, params, position)
    if military == 1 then
        self.military1:makeSquad(params, position)
    else
        self.military2:makeSquad(params, position)
    end
end


function Battlefield:makeFightUnit(military, params, position)
    if military == 1 then
        self.military1:makeFightUnit(params, position)
    else
        self.military2:makeFightUnit(params, position)
    end

    --self:refreshMapUI()
end

return Battlefield
